module uart_rx (
    input               clk,
    input               rst_n,
    input               rx,
    input      [1:0]    sw,
    output reg [7:0]    rx_data,
    output reg          rx_done
);

wire                         rx_check;

//比特率计数器
reg            [12:0]       cnt;
reg                         add_cnt;
wire                        end_cnt;   

//bit计数器
reg            [3:0]        cnt_bit;  
wire                        add_cnt_bit;
wire                        end_cnt_bit;

//下降沿检测
reg            [1:0]        rx_r;
wire                        rx_start;

reg            [10:0]       rx_data_r;

reg            [12:0]       baud;

always @(*) begin
    case(sw)
    2'b00:      baud = 5208;          //9600波特率
    2'b01:      baud = 3472;          //14400波特率
    2'b10:      baud = 1302;          //38400波特率
    2'b11:      baud = 434;           //115200波特率
    default:    baud = 5208;           
    endcase
end

always @(posedge clk or negedge rst_n) begin
    if(!rst_n)begin
        cnt <= 0;
    end 
    else if(add_cnt)begin
        if(end_cnt)begin
            cnt <= 0;
        end
        else begin
            cnt <= cnt + 1;
        end
    end
    else begin
        cnt <= cnt;
    end
end

assign end_cnt = add_cnt && (cnt == baud-1)||(cnt_bit == 4'd10 && cnt == ((baud-1)>>1));

always @(posedge clk or negedge rst_n)begin
    if(!rst_n)begin
        add_cnt <= 1'b0;
    end
    else if(rx_start)begin
        add_cnt <= 1'b1;
    end
    else if(end_cnt_bit||(cnt_bit == 4'd10 && cnt == ((baud-1)>>1)))begin
        add_cnt <= 1'b0;
    end
end

always @(posedge clk or negedge rst_n) begin
    if(!rst_n)begin
        rx_r <= 2'b00;
    end
    else begin
        rx_r <= {rx_r[0],rx};
    end 
end

assign rx_start = ~rx_r [0] & rx_r [1];

always @(posedge clk or negedge rst_n) begin
    if(!rst_n)begin
        cnt_bit <= 0;
    end
    else if(add_cnt_bit)begin
        if(end_cnt_bit)begin
            cnt_bit <= 0;
        end
        else begin
            cnt_bit <= cnt_bit + 1;
        end
    end
    else begin
        cnt_bit <= cnt_bit;
    end
end

assign add_cnt_bit = end_cnt ;
assign end_cnt_bit = add_cnt_bit && cnt_bit == 4'd11-1;

always @(posedge clk or negedge rst_n) begin
    if(!rst_n)begin
        rx_data_r <= 11'b11111111111;
    end
    else if(cnt == (baud - 1)>>2)begin
        rx_data_r[cnt_bit] <= rx; 
    end
end

assign rx_check = ~^ rx_data_r[8 :1];

always @(posedge clk or negedge rst_n) begin
    if(!rst_n)begin
        rx_data <= 8'hff;
    end
    else if((cnt == (baud - 1)>>1)&&cnt_bit == 4'd9)begin
        if((rx_check == rx_data_r[9]))begin
            rx_data <= rx_data_r[8:1];
        end
    else begin
        rx_data <=8'hff;
    end
    end
end

always @(posedge clk or negedge rst_n) begin
    if(!rst_n)begin
        rx_done <= 1'b0;
    end
    else if(end_cnt_bit)begin
        rx_done <= 1'b1;
    end
    else begin
        rx_done <= 1'b0;
    end
end
endmodule